/**
 * JS 引擎执行代码的流程
 *  1. 预解析
 *  2. 执行代码
 *
 * 预解析分为变量预解析和函数预解析
 *  ● 变量预解析：又称变量提升，把变量声明提升到当前作用域的最前面，不包含赋值操作
 *  ● 函数预解析：又称函数提升，把命名函数提升到当前作用域的最前面，不包含匿名函数
 */

// 变量预解析 >>>
/**
 * var str
 * console.log(str)
 * str = 'Hello world!'
 */
console.log(str) // undefined
var str = 'Hello world!'
// 变量预解析 <<<

// 函数预解析 >>>
/**
 * function fn() {
 *   console.log('fn')
 * }
 * fn()
 */
fn() // fn
function fn() {
  console.log('fn')
}
// 函数预解析 <<<

// 变量预解析（匿名函数） >>>
/**
 * var fn2
 * fn2()
 * fn2 = function () {
 *   console.log('fn2')
 * }
 */
fn2() // TypeError: fn2 is not a function
var fn2 = function () {
  console.log('fn2')
}
// 变量预解析（匿名函数） <<<
